#ifndef __BSP_SPI_FLASH_H
#define __BSP_SPI_FLASH_H

#include "gd32f4xx.h"

#define RCU_FLASH_SPI_PERIPH			RCU_SPI4
#define RCU_FLASH_SPI_PORT_PERIPH		RCU_GPIOF
#define FLASH_SPI_PORT				GPIOF
#define FLASH_SPI					SPI4


#define SPI_NSS_PIN			GPIO_PIN_6
#define SPI_SCK_PIN			GPIO_PIN_7
#define SPI_MISO_PIN		GPIO_PIN_8
#define SPI_MOSI_PIN		GPIO_PIN_9

#define DUMMY_BYTE			0xff
#define	SPI_TIMEOUT			1000

#define FLASH_CS_HIGH()		gpio_bit_set(FLASH_SPI_PORT, SPI_NSS_PIN)
#define FLASH_CS_LOW()		gpio_bit_reset(FLASH_SPI_PORT, SPI_NSS_PIN)

#define W25Q80 	0XEF13
#define W25Q16 	0XEF14
#define W25Q32 	0XEF15
#define W25Q64 	0XEF16
#define W25Q128	0XEF17

#define W25X_WriteEnable		0x06
#define W25X_WriteDisable		0x04
#define W25X_ReadStatusReg		0x05
#define W25X_WriteStatusReg		0x01
#define W25X_ReadData			0x03
#define W25X_FastReadData		0x0B
#define W25X_FastReadDual		0x3B
#define W25X_PageProgram		0x02
#define W25X_BlockErase			0xD8
#define W25X_SectorErase		0x20
#define W25X_ChipErase			0xC7
#define W25X_PowerDown			0xB9
#define W25X_ReleasePowerDown	0xAB
#define W25X_DeviceID			0xAB
#define W25X_ManufactDeviceID	0x90
#define W25X_JedecDeviceID		0x9F

#define MAX_FLASH_ADDRESS		0x7fffff
#define TIME_OUT				0xff

void FLASH_SPI_Init(void);
uint8_t FLASH_SPI_ReadWriteByte(uint8_t TxData, uint8_t *pError);
uint16_t W25QXX_Init(uint8_t *pError);
uint8_t W25QXX_ReadSR(uint8_t *pError);
void W25QXX_Write_SR(uint8_t sr, uint8_t *pError);
void W25QXX_Write_Enable(uint8_t *pError);
void W25QXX_Write_Disable(uint8_t *pError);
uint16_t W25QXX_ReadID(uint8_t *pError);
uint8_t W25QXX_Read(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);
uint8_t W25QXX_Write_Page(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
uint8_t W25QXX_Write_NoCheck(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
uint8_t W25QXX_Write(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
void W25QXX_Erase_Chip(uint8_t *pError);
void W25QXX_Erase_Sector(uint32_t Dst_Addr, uint8_t *pError);
void W25QXX_Wait_Busy(uint8_t *pError);
void W25QXX_PowerDown(uint8_t *pError);
void W25QXX_WAKEUP(uint8_t *pError);


#endif /* __BSP_SPI_FLASH_H */
